﻿using System.Collections.Generic;
using Engine;
using Engine.Graphics;
using Game;

namespace Mekiasm
{
    public class AtomicDecomposer : Item,Interface.IChargeAbleItem
    {
        public BlockMesh blockMesh = new BlockMesh();
        public Texture2D texture;
        public List<int> liansuoID = new List<int>() {
            RubberWood.Index, OakWoodBlock.Index,BirchWoodBlock.Index,MimosaWoodBlock.Index,SpruceWoodBlock.Index,
            CopperOreBlock.Index, SulphurOreBlock.Index, IronOreBlock.Index, CoalOreBlock.Index, DiamondOreBlock.Index,
            GermaniumOreBlock.Index , OreLead.Index,OreTin.Index,OreUranium.Index, SaltpeterOreBlock.Index

        };
        public MutiBlockCheck newMuti = new MutiBlockCheck();

        public enum Mode
        {
            Normal,
            Accurate,
            Slow,
            Fast,
            Chunk
        }

        public Mode DigMode = Mode.Normal;

        public static int Index;

        public ComponentEnergyMachine.FuelType ChargeFuelType => ComponentEnergyMachine.FuelType.Electric;

        public long MaxAmount => GetMaxPower();

        public AtomicDecomposer() : base("原子分解机")
        {
            Model model = ContentManager.Get<Model>("Mekiasm/Models/AtomicDecomposer");
            Matrix bone = BlockMesh.GetBoneAbsoluteTransform(model.FindMesh("Atom_main").ParentBone);
            texture = ContentManager.Get<Texture2D>("Mekiasm/Textures/AtmoicDecomposer");
            BlockMesh mesh = new BlockMesh();
            mesh.AppendModelMeshPart(model.FindMesh("Atom_main").MeshParts[0], bone, false, false, false, false, Color.White);
            blockMesh.AppendBlockMesh(mesh);
            blockMesh.TransformPositions(Matrix.CreateTranslation(0f, -1f, 0f));
            
        }
        public override bool IsCrushWhenNoPower()
        {
            return false;
        }

        public override int GetMaxPower()
        {
            return 10240;
        }

        public override bool OnUse(Ray3 aim, ComponentMiner componentMiner, TerrainRaycastResult? raycast)
        {
            SaveItemSystem.GetBlockData(componentMiner.ActiveBlockValue,out var data);
            switch (DigMode)
            {
                case Mode.Chunk:
                    if (raycast.HasValue)
                    {
                        int v = raycast.Value.Value;
                        var point = raycast.Value.CellFace.Point;
                        var block = BlocksManager.Blocks[Terrain.ExtractContents(v)];
                        if (block is GrassBlock || block is DirtBlock)
                        {
                            if (data != null)
                            {
                                SaveItemSystem.ChangePower(componentMiner.ActiveBlockValue, GetOutputLimit());
                                ILibrary.SubsystemTerrain.ChangeCell(point.X, point.Y, point.Z, SoilBlock.Index);
                            }
                            else
                            {
                                DisplayMsg(componentMiner.ComponentPlayer, "电量不足");
                            }
                        }
                    }
                    break;
            }
            return true;
        }


        public override void DrawBlock(PrimitivesRenderer3D primitivesRenderer, int value, Color color, float size, ref Matrix matrix, DrawBlockEnvironmentData environmentData)
        {
            BlocksManager.DrawMeshBlock(primitivesRenderer, blockMesh, texture, Color.White, size, ref matrix, environmentData);
        }

        public override bool OnDigged(int value, ComponentMiner componentMiner, TerrainRaycastResult raycastResult)
        {
            SaveItemSystem.GetBlockData(componentMiner.ActiveBlockValue, out Common.SaveItem saveItem);
            var PowerUse = GetOutputLimit();
            switch (DigMode)
            {
                case Mode.Accurate:
                    PowerUse *= 20;
                    break;
                case Mode.Fast:
                    PowerUse *= 4;
                    break;
                case Mode.Chunk:
                    PowerUse *= 2;
                    break;
            }
            if (saveItem != null && saveItem.fuelAmount >= PowerUse)
            {
                CellFace cellFace = raycastResult.CellFace;
                Point3 digPoint = cellFace.Point;
                if (liansuoID.Contains(value))
                {
                    newMuti.findSameBlocks(ILibrary.SubsystemTerrain.Terrain, digPoint, new List<MutiBlockCheck.AcceptBlock>() { new MutiBlockCheck.AcceptBlock(value) });
                    for (int i = 0; i < newMuti.cache.Count; i++)
                    {
                        ILibrary.Dig(4, componentMiner, newMuti.cache[i], raycastResult.Value, DigMode == Mode.Accurate);
                    }
                    SaveItemSystem.ChangePower(componentMiner.ActiveBlockValue, -newMuti.cache.Count * PowerUse);
                    return false;
                }
                else
                {                    
                    SaveItemSystem.ChangePower(componentMiner.ActiveBlockValue, -PowerUse);
                }
            }
            return true;
        }

        public int GetOutputLimit()
        {
            return 32;
        }

        public override float GetShovelPower(int value)
        {
            switch (DigMode)
            {
                case Mode.Fast: return 12f;
            }
            return 4f;
        }
        public override float GetHackPower(int value)
        {
            switch (DigMode)
            {
                case Mode.Fast: return 12f;
            }
            return 4f;
        }
        public override float GetQuarryPower(int value)
        {
            switch (DigMode)
            {
                case Mode.Fast: return 12f;
            }
            return 4f;
        }
        public override bool HasExtraSet(int value)
        {
            return true;
        }
        public override void ClickExtraSet(ComponentPlayer player, int value)
        {
            int mode = (int)DigMode;
            mode++;
            if (mode == 5) mode = 0;
            DigMode = (Mode)mode;
            switch (DigMode)
            {
                case Mode.Fast:
                    DisplayMsg(player, "快速模式");
                    break;
                case Mode.Accurate:
                    DisplayMsg(player, "精准模式");
                    break;
                case Mode.Slow:
                    DisplayMsg(player, "慢速模式");
                    break;
                case Mode.Chunk:
                    DisplayMsg(player, "锄地模式");
                    break;
                case Mode.Normal:
                    DisplayMsg(player, "标准模式");
                    break;
            }
        }
        public override bool IsPlaceable_(int value)
        {
            return false;
        }

        public override float GetBlockHealth(int value)
        {
            SaveItemSystem.GetBlockData(value, out var d);
            if (d == null) return -1f;
            else return GetCurrentAmount(value) / (float)GetMaxPower();
        }

        public long GetCurrentAmount(int value)
        {
            SaveItemSystem.GetBlockData(value, out var d);
            if (d == null) return 0;
            else return d.fuelAmount;
        }

        public int SetCurrentAmount(int value, int fuelValue, long varAmount)
        {
            return SaveItemSystem.ChangePower(value, varAmount, fuelValue);
        }

        public int GetChargeFuelValue(int value)
        {
            return 0;
        }

        public bool CanAcceptFuel(int fuelValue)
        {
            return true;
        }

    }
}
